package com.elminster.graphic.impl;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.RenderingHints;
import java.util.List;

import com.elminster.graphic.GraphicBase;
import com.elminster.graphic.IGraphic;
import com.elminster.graphic.entity.GraphicEntity;

public class LinedGraphicImpl extends GraphicBase implements IGraphic {
    
    private static final int bold = 3;
    private static final Insets insets = new Insets(5, 5, 5 + bold, 5);
    private Point[] points;
    private double max = Double.MIN_VALUE;
    private double min = Double.MAX_VALUE;

    public void draw(Graphics g) {
        if (isMerge()) {
            entity = meger();
        }
        if (null == entity || entity.isEmpty()) {
            return;
        }
        getDefference(entity);
        
        double dy = max - min;
        
        points = new Point[entity.size()];
        double dx = (getWidth() - insets.left - insets.right) / (entity.size() - 1);
        int x, y;
        for (int i = 0; i < entity.size(); i++) {
            double value = entity.get(i).getValue();
            y = (int) (getHeight() - insets.top - ((value - min) / dy * (getHeight() - insets.top - insets.bottom)));
            x =  insets.left + (int) (dx * i);
            points[i] = new Point(x, y);
        }
        
        drawLine(g);
    }
    
    private void getDefference(List<GraphicEntity> entities) {
        for (GraphicEntity entity : entities) {
            if (entity.getValue() > max) {
                max = entity.getValue();
            }
            if (entity.getValue() < min) {
                min = entity.getValue();
            }
        }
    }
    
    private void drawLine(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        Color oraginColor = g2d.getColor();
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING , RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setColor(Color.white);
        if (null == points || 0 == points.length) {
            ;
        } else if (1 == points.length) {
            drawPoint(g2d, new Point(width / 2, points[0].y));
        } else {
//            for (int i = 0; i < points.length - 1; i++) {
//                drawPoint(g, points[i]);
//                g.drawLine(points[i].x, points[i].y, points[i + 1].x, points[i + 1].y);
//            }
//            drawPoint(g, points[points.length - 1]);
            drawLine(g2d, bold);
        }
        
        g2d.setColor(oraginColor);
    }
    
    private void drawPoint(Graphics g, Point p) {
        g.fillOval(p.x - 1, p.y - 1, 3, 3);
        g.drawLine(p.x, getHeight(), p.x, 0);
    }
    
    private void drawLine(Graphics g, int bold) {
        for (int i = 0; i < points.length - 1; i++) {
            int x1 = points[i].x;
            int y1 = points[i].y;
            int x2 = points[i + 1].x;
            int y2 = points[i + 1].y;
            for (int j = 0; j < bold; j++) {
                g.drawLine(x1, y1 + j, x2, y2 + j);
            }
        }
    }
}
